// -------------------------------------------------------
// Copyright (c) Wild West Games 2006, All Rights Reserved
// -------------------------------------------------------

#include "cbase.h"
#include "hudelement.h"
#include "hud_macros.h"
#include "iclientmode.h"
#include "c_baseplayer.h"
#include "Wanted_Shared/wanted_shareddefs.h"

#include <vgui/IScheme.h>
#include <vgui/ISurface.h>
#include <vgui_controls/Panel.h>

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

static const char* g_szScopeStrings[] =
{
	"ScopeWF",
	"Scope357",
	"ScopeSharps",
	"ScopeYellowboy"
};

/**
 * Simple HUD element for displaying a sniper scope on screen
 */
class CHudScope : public vgui::Panel, public CHudElement
{
	DECLARE_CLASS_SIMPLE( CHudScope, vgui::Panel );

public:
	CHudScope( const char *pElementName );

	void Init();
	void MsgFunc_ShowScope( bf_read &msg );
	void MsgFunc_HideScope( bf_read &msg );

protected:
	virtual void ApplySchemeSettings(vgui::IScheme *scheme);
	virtual void Paint( void );

private:
	ScopeType		m_iScopeToShow;
    CHudTexture*	m_pScopes[WANTED_SCOPE_TOTAL];
};


DECLARE_HUDELEMENT( CHudScope );
DECLARE_HUD_MESSAGE( CHudScope, ShowScope );
DECLARE_HUD_MESSAGE( CHudScope, HideScope );

using namespace vgui;


/**
 * Constructor - generic HUD element initialization stuff. Make sure our 2 member variables
 * are instantiated.
 */
CHudScope::CHudScope( const char *pElementName ) : CHudElement(pElementName), BaseClass(NULL, "HudScope")
{
	vgui::Panel *pParent = g_pClientMode->GetViewport();
	SetParent( pParent );

	m_iScopeToShow = WANTED_SCOPE_NONE;

	// Init scope texture pointers
	for (int i = 0 ; i < WANTED_SCOPE_TOTAL ; ++i)
	{		
		m_pScopes[i] = 0;
	}

	// Scopes will not show when the player is dead
	SetHiddenBits( HIDEHUD_PLAYERDEAD );
}


/**
 * Hook up our hud message, and make sure we are not showing the scope
 */
void CHudScope::Init()
{
	HOOK_HUD_MESSAGE( CHudScope, ShowScope );
	HOOK_HUD_MESSAGE( CHudScope, HideScope );
	m_iScopeToShow = WANTED_SCOPE_NONE;
}


/**
 * Load  in the scope material here
 */
void CHudScope::ApplySchemeSettings( vgui::IScheme *scheme )
{
	BaseClass::ApplySchemeSettings(scheme);

	// Load in scope images - referenced from scripts/hud_textures.txt
	for (int i = 0 ; i < WANTED_SCOPE_TOTAL ; ++i)
	{
		if (!m_pScopes[i])
		{
			m_pScopes[i] = gHUD.GetIcon(g_szScopeStrings[i]);
		}
	}

	// Force HUD element to cover entire screen on resize
	SetSize(ScreenWidth(), ScreenHeight());
}


/**
 * Simple - if we want to show the scope, draw it. Otherwise don't.
 */
void CHudScope::Paint( void )
{
	// This will draw the scope at the origin of this HUD element, and
	// stretch it to the width and height of the element. As long as the
	// HUD element is set up to cover the entire screen, so will the scope
	if (m_iScopeToShow < WANTED_SCOPE_TOTAL)
	{
		if (m_pScopes[m_iScopeToShow])
		{
			int iScopeWide = m_pScopes[m_iScopeToShow]->Width();
			int iScopeTall = m_pScopes[m_iScopeToShow]->Height();
			
			int iVertBorderWidth = (GetWide() - iScopeWide) / 2;
			int iHorizBorderHeight = (GetTall() - iScopeTall) / 2;

			m_pScopes[m_iScopeToShow]->DrawSelf(iVertBorderWidth, iHorizBorderHeight, Color(255,255,255,255));

			vgui::surface()->DrawSetColor(Color(0,0,0,255));
			
			// Vertical borders
			vgui::surface()->DrawFilledRect(0,0,iVertBorderWidth,GetTall());
			vgui::surface()->DrawFilledRect(GetWide() - iVertBorderWidth, 0, GetWide(), GetTall());

			// Horizontal letterbox borders
			vgui::surface()->DrawFilledRect(iVertBorderWidth, GetWide() - iVertBorderWidth, 0, iHorizBorderHeight);
			vgui::surface()->DrawFilledRect(iVertBorderWidth, GetWide() - iVertBorderWidth, GetTall()-iHorizBorderHeight, GetTall());
		}
	}
}


/**
* how the scope type specified in the message
*/
void CHudScope::MsgFunc_ShowScope(bf_read &msg)
{
	int msgContents = msg.ReadByte();
	if (msgContents < WANTED_SCOPE_TOTAL || msgContents == WANTED_SCOPE_NONE)
	{
		m_iScopeToShow = static_cast<ScopeType> (msgContents);
	}
	else
	{
		m_iScopeToShow = WANTED_SCOPE_NONE;
		DevWarning("Invalid scope type in ShowScope message - %d\n", msgContents);
	}
}



/**
* If the scope type specified in the message is the one currently being shown,
* stop drawing the scope
*/
void CHudScope::MsgFunc_HideScope(bf_read &msg)
{
	int msgContents = msg.ReadByte();
	if (msgContents < WANTED_SCOPE_TOTAL || msgContents == WANTED_SCOPE_NONE)
	{
		ScopeType iScopeToHide = static_cast<ScopeType> (msgContents);
		if (iScopeToHide == m_iScopeToShow)
		{
			m_iScopeToShow = WANTED_SCOPE_NONE;
		}
	}
	else
	{
		DevWarning("Invalid scope type in HideScope message - %d\n", msgContents);
	}
}